<?php
/**
 * Nordic Repository
 * 
 * LICENSE
 * 
 * The new BSD license is applied on this source-file. For further
 * information please visit http://license.nordic-dev.de/newbsd.txt
 * or send an email to andre.moelle@gmail.com.
 */

/**
 * This is the base-class for protectors.
 * 
 * @category   Nordic
 * @package    Nordic_Security
 * @copyright  2007 Nordic Development
 * @license    http://license.nordic-dev.de/newbsd.txt (New-BSD license)
 * @author     Andre Moelle <andre.moelle@gmail.com>
 * @version    $Id: Abstract.php 3 2007-07-08 09:21:42Z andre.moelle $
 */
abstract class Nordic_Security_Protector_Abstract extends Zend_Controller_Plugin_Abstract
{
	/**
	 * Protectable controller.
	 * 
	 * @var Nordic_Security_Protectable
	 */
	protected $_controller;
	
	/**
	 * Name of the protected controller.
	 * 
	 * @var string
	 */
	protected $_name = '';
	
	/**
	 * Options which are necessary for the protector.
	 * 
	 * @var array
	 */
	protected $_options = array();
	
	/**
	 * Sets the necessary options and the protected controller.
	 * 
	 * @param Nordic_Security_Protectable $controller controller which should be protected
	 * @param array $options options which are necessary for the protector
	 * @return void
	 */
	public function __construct (Nordic_Security_Protectable $controller, array $options = array())
	{
		$this->setController($controller);
		$this->setOptions($options);
	}
	
	/**
	 * Returns true if the controller-name and the requested controller match.
	 * 
	 * @param void
	 * @return boolean
	 */
	public function applies ()
	{
		return (strtolower($this->getName()) == strtolower($this->getRequest()->getControllerName()));
	}
	
	/**
	 * Returns the controller.
	 * 
	 * @param void
	 * @return Nordic_Security_Protectable
	 */
	public function getController ()
	{
		return $this->_controller;
	}
	
	/**
	 * Returns the name of the controller.
	 * 
	 * @param void
	 * @return string
	 */
	public function getName ()
	{
		if($this->_name == null)
		{
			$refl = new ReflectionObject($this->getController());
			
			$this->_name = strtolower(
				substr(
					$refl->getName(),
					0,
					strpos($refl->getName(), 'Controller')
				)
			);
		}
		
		return $this->_name;
	}
	
	/**
	 * Returns the options.
	 * 
	 * @param void
	 * @return array
	 */
	public function getOptions ()
	{
		return $this->_options;
	}
	
	/**
	 * Throws an exception unless it is overwritten.
	 * 
	 * @throws Nordic_Security_Exception
	 * @param void
	 * @return void
	 */
	public function preDispatch (Zend_Controller_Request_Abstract $request)
	{
		if(!$this->applies())
		{
			return;
		}
		
		if(!$this->protect())
		{
			$this->getController()->wasProtected();
			$this->getController()
				 ->getResponse()
				 ->setHttpResponseCode(403)
				 ->sendResponse();
			exit;
		}
	}
	
	/**
	 * Implementation of the protector-algorithm.
	 * 
	 * If the user is allowed to access the action, true is returned.
	 * Otherwise false is returned.
	 * 
	 * @param void
	 * @return boolean
	 */
	abstract public function protect ();
	
	/**
	 * Sets the protectable controller.
	 * 
	 * @param Nordic_Security_Protectable $controller new protectable controller
	 * @return void
	 */
	public function setController (Nordic_Security_Protectable $controller)
	{
		$this->_controller = $controller;
	}
	
	/**
	 * Sets the options.
	 * 
	 * @param array $options options
	 * @return void
	 */
	public function setOptions (array $options)
	{
		$this->_options = $options;
	}
}
?>